﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>ASP.NET Boilerplate</title>
<link type="text/css" rel="stylesheet" href="bootstrap.min.css" />
</head>

<body>

<div class="document-contents">

<h3>Introduction</h3>
<p>Notifications are used to <strong>inform</strong> users on specific events in 
the system. It's especially used in social webs. ASP.NET Boilerplate provides a
<strong>pub/sub</strong> based <strong>real time</strong> notification 
infrastructure.</p>
	<h4>Sending Models</h4>
	<p>There are two ways of sending notifications to users:</p>
	<ul>
		<li>User <strong>subscribes</strong> to a specific notification type. 
		Then we <strong>publish</strong> a notification of this type which is 
		delivered to all subscribed users. This is <strong>pub/sub</strong> 
		model.</li>
		<li>We can <strong>directly send</strong> a notification to <strong>
		target user(s)</strong>.</li>
	</ul>
	<h4>Types</h4>
	<p>There are also two types of notifications:</p>
	<ul>
		<li><strong>General notifications</strong> are arbitrary type of 
		notifications. "Notify me if a user sends me a friendship request" is an 
		example of this type notifications.</li>
		<li><strong>Entity notifications</strong> are associated to a 
		specific entity. "Notify me if a user comment on <strong>this</strong> 
		photo" is an entity based notification since it's associated to a 
		specific photo entity.</li>
	</ul>
	<h4>Data</h4>
	<p>A notification includes a <strong>notification data</strong>. For 
	example: "Notify me if a user sends me a friendship request" notification 
	may have two data properties: <em>sender user name</em> (which user sent 
	this friendship request) and <em>request note</em> (a note that user did 
	write in the request). It's obvious that the notification data is tightly 
	coupled to notification types. Different notification types have different 
	data types.</p>
	<p>Notification data is <strong>optional</strong>. Some notifications may 
	not require a data.</p>
	<h4>Severity</h4>
	<p>There are 5 levels of notification severity, defined in <strong>
	NotificationSeverity</strong> enum: <strong>Info</strong>, <strong>Success</strong>,
	<strong>Warn</strong>, <strong>Error</strong> and <strong>Fatal</strong>. 
	Default value is <strong>Info</strong>.</p>

	<div class="bs-callout bs-callout-warning">
		<h4>About Notification Persistence</h4>
	<p>See <em>Notification Store</em> section for more information on 
	notification 
	persistence.</p>
	</div>

	<h3>Subscribe to Notifications</h3>
	<p><strong>INotificationSubscriptionManager</strong> provides API to <strong>
	subscribe</strong> to notifications. Examples:</p>
	<pre lang="cs">public class MyService : ITransientDependency
{
    private readonly INotificationSubscriptionManager _notificationSubscriptionManager;

    public MyService(<strong>INotificationSubscriptionManager notificationSubscriptionManager</strong>)
    {
        _notificationSubscriptionManager = notificationSubscriptionManager;
    }

    //Subscribe to a general notification
    public async Task Subscribe_SentFrendshipRequest(long userId)
    {
<strong>        await _notificationSubscriptionManager.SubscribeAsync(userId, &quot;SentFrendshipRequest&quot;);
</strong>    }

    //Subscribe to an entity notification
    public async Task Subscribe_CommentPhoto(long userId, Guid photoId)
    {
        <strong>await _notificationSubscriptionManager.SubscribeAsync(userId, &quot;CommentPhoto&quot;, new EntityIdentifier(typeof(Photo), photoId));
</strong>    }
}</pre>
	<p>First, we <a href="/Pages/Documents/Dependency-Injection">injected</a> <strong>INotificationSubscriptionManager</strong>. 
	First method subscribe to a <strong>general notification</strong>. User wants to get notified 
	when someone sends a friendship request. Second one subscribes to a 
	notification related to a <strong>specific entity</strong> (Photo). User wants to get 
	notified if anyone writes comment to specified photo.</p>
	<p>Every notification type should have <strong>unique names</strong> (like
	<em>SentFrendshipRequest</em> 
	and <em>CommentPhoto</em> in this samples)</p>
	<p><strong>INotificationSubscriptionManager</strong> has also <strong>
	UnsubscribeAsync, IsSubscribedAsync, GetSubscriptionsAsync</strong>... 
	methods to manage subscriptions.</p>
	<h3>Publish Notifications</h3>
	<p><strong>INotificationPublisher</strong> is used to publish notifications. 
	Examples:</p>
	<pre lang="cs">public class MyService : ITransientDependency
{
    private readonly INotificationPublisher _notiticationPublisher;

    public MyService(<strong>INotificationPublisher notiticationPublisher</strong>)
    {
        _notiticationPublisher = notiticationPublisher;
    }

    //Send a general notification to a specific user
    public async Task Publish_SentFrendshipRequest(string senderUserName, string friendshipMessage, long targetUserId)
    {
        <strong>await _notiticationPublisher.PublishAsync(&quot;SentFrendshipRequest&quot;, new SentFrendshipRequestNotificationData(senderUserName, friendshipMessage), userIds: new[] { targetUserId });
</strong>    }

    //Send an entity notification to a specific user
    public async Task Publish_CommentPhoto(string commenterUserName, string comment, Guid photoId, long photoOwnerUserId)
    {
        <strong>await _notiticationPublisher.PublishAsync(&quot;CommentPhoto&quot;, new CommentPhotoNotificationData(commenterUserName, comment), new EntityIdentifier(typeof(Photo), photoId), userIds: new[] { photoOwnerUserId });
</strong>    }

    //Send a general notification to all subscribed users with a specified severity level
    public async Task Publish_LowDisk(int remainingDiskInMb)
    {
<strong>        var data = new NotificationData();
        data[&quot;RemainingDiskInMb&quot;] = remainingDiskInMb;

        await _notiticationPublisher.PublishAsync(&quot;System.LowDisk&quot;, data, severity: NotificationSeverity.Warn);
</strong>    }
}</pre>
	<p>In the first example, we published a notification to a single user. 
	<em>SentFrendshipRequestNotificationData</em> should be derived from <strong>
	NotificationData</strong> like that:</p>
	<pre lang="cs">[Serializable]
public class SentFrendshipRequestNotificationData : <strong>NotificationData</strong>
{
    public string SenderUserName { get; set; }

    public string FriendshipMessage { get; set; }

    public SentFrendshipRequestNotificationData(string senderUserName, string friendshipMessage)
    {
        SenderUserName = senderUserName;
        FriendshipMessage = friendshipMessage;
    }
}</pre>
	<p>In the second example, we sent a notification to a <strong>specific user</strong> 
	for a <strong>specific entity</strong>. Notification data classes don't need 
	to be <strong>serialzable</strong> normally (since JSON serialization is 
	used by default). But it's suggested to mark it as serializable since you 
	may need to move notifications between applications and may want to use 
	binary serialization in the future. Also, as declared before, notification 
	data is optional and may not be required for all notifications.</p>
	<p><strong>Note</strong>: If we publish a notification to <strong>specific 
	users</strong>, they <strong>don't need</strong> to be subscribed to those 
	notifications.</p>
	<p>In the third example, we did not define a dedicated notification data 
	class. instead, directly used built-in <strong>NotificationData</strong> 
	with <strong>dictionary</strong> based data, and published notification as '<strong>Warn</strong>'. 
	Strong typed notification data is better for type safety, but notification 
	data dictionary properties also can be useful in some cases.</p>
	<h3>User Notification Manager</h3>
	<p><strong>IUserNotificationManager</strong> is used to manage notifications 
	of users. It has methods to <strong>get</strong>, <strong>update</strong> or 
	<strong>delete</strong> notifications for a 
	user. You can use it to prepare a notification list page for a 
	user.</p>
	<h3>Real Time Notifications</h3>
	<p>Notification system uses <strong>IRealTimeNotifier</strong> to send real 
	time notifications to users. This can be implemented with any type of real 
	time communication system. It's implemented using <strong>SignalR</strong> 
	in a seperated package. <a href="/Templates">Startup templates</a> have 
	already SignalR installed. See
	<a href="/Pages/Documents/SignalR-Integration">SignalR Integration document</a> 
	for more information.</p>
	<p><strong>Note</strong>: Notification system calls <strong>
	IRealTimeNotifier</strong> asynchronously in a
	<a href="/Pages/Documents/Background-Jobs-And-Workers"><strong>background 
	job</strong></a>. So, notifications may be sent with a small delay.</p>
	<h4>Client Side</h4>
	<p>ASP.NET Boilerplate triggers a global event in the client side:</p>
	<pre lang="js">abp.event.on(&#39;<strong>abp.notifications.received</strong>&#39;, function (userNotification) {
    console.log(userNotification);
});</pre>
	<p><strong>abp.notifications.received</strong> event is triggered for each 
	received real time notification. You can register to this event as shown 
	above to get notifications. See
	<a href="/Pages/Documents/Javascript-API/Event-Bus">event bus</a> 
	documentation for more information on events.</p>
	<h3>Notification Store</h3>
	<p>Notification system uses <strong>INotificationStore</strong> to persist 
	notifications. This should be implemented in order to make notification 
	system properly working. You can implement it yourself or use <strong>
	<a href="/Pages/Documents/Zero/Overall">module-zero</a></strong> which 
	already implements it.</p>

</div>

</body>

</html>
